package com.je.gateway.filter;

import com.google.common.base.Strings;
import com.je.common.auth.impl.account.Account;
import com.je.common.auth.token.AuthSession;
import com.je.gateway.router.loader.SecuriryUrlResourceLoader;
import com.je.gateway.util.SecurityUserHolder;
import com.je.gateway.util.SpringContextHolder;
import com.je.gateway.util.UrlMatcher;
import com.je.gateway.xml.ConfigResourceLoader;
import com.je.gateway.security.PlatformInputSecurityValidatorFactory;
import com.je.gateway.router.model.security.SecurityUrl;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.foundation.common.http.HttpStatus;
import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
import org.apache.servicecomb.swagger.invocation.Response;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.Map;

public class GatewaySecurityUserServerFilter extends AbstractHttpServerFilter {

    private SecurityUrl configurations = new SecurityUrl();

    private ConfigResourceLoader<SecurityUrl> xmlConfigResourceLoader = new SecuriryUrlResourceLoader();

    private UrlMatcher urlMatcher;

    public GatewaySecurityUserServerFilter() {
        loadConfigurations();
    }

    @Override
    public int getOrder() {
        return 1;
    }

    @Override
    public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx requestEx) {
        //从这里获取是因为前边已经统一设置好了
        String token = requestEx.getHeader(GatewayFilterConstants.X_AUTH_TOKEN);
        String isOpen = requestEx.getHeader("isOpen");
        if ("0".equals(isOpen) && Strings.isNullOrEmpty(token)) {
            return buildRejectResponse("此接口没开放，请先登录后再访问！");
        }

        if ("0".equals(isOpen)) {
            invocation.getContext().put(GatewayFilterConstants.X_AUTH_TOKEN, token);
            //构建登录用户
            RedisTemplate<String, Object> redisTemplate = SpringContextHolder.getBean("redisTemplate");
            StringRedisTemplate stringRedisTemplate = SpringContextHolder.getBean("stringRedisTemplate");
            String authId = stringRedisTemplate.opsForValue().get("authorization:token:" + token);
            if (Strings.isNullOrEmpty(authId)) {
                return buildRejectResponse("此token已失效，请重新登录！");
            }
            Object sessionObj = redisTemplate.opsForValue().get("authorization:session:" + authId);
            if (sessionObj == null) {
                return buildRejectResponse("此token已失效，请重新登录！");
            }
            AuthSession session = (AuthSession) sessionObj;
            if (!session.getDataMap().containsKey("account")) {
                return buildRejectResponse("无法根据token获取登录信息，请重新登录！");
            }
            Account account = (Account) session.getDataMap().get("account");
            SecurityUserHolder.put(account);
        }
        HttpServletRequestEx hsre = invocation.getRequestEx();
        Map<String, String[]> params = hsre.getParameterMap();
        for (Map.Entry<String, String[]> eachEntry : params.entrySet()) {
            Response response = PlatformInputSecurityValidatorFactory.validatorCharacter(eachEntry.getKey(), eachEntry.getValue()[0]);
            if (response != null) {
                return response;
            }
        }
        return null;
    }

    private Response buildRejectResponse(String message) {
        return Response.create(new HttpStatus(401, "Unauthorized"), message);
    }

    private void loadConfigurations() {
        configurations = xmlConfigResourceLoader.load();
        urlMatcher = new UrlMatcher(configurations.getPatterns());
    }

}
